AnyFunSuiteとMatchersを併用してScalaのテストケースを書いてみた(Scala 2.11.12 & ScalaTest 3.1.2)
はじめに
Scalaのテストケース作成に着手し、最初に作成したテストがsbt test
で正常に通過する段階まで辿り着きました。一番大変だったのは、テストケースのサンプルコードが大体古いためかDeprecatedのアラートが大量につくところです。
ScalaTestにてAnyFunSuite
とMatchers
を使ってのテスト記述パターンを備忘録込めてまとめました。
導入
以下のようにbuild.sbtへ追記します。
scalaVersion := "2.11.12" libraryDependencies ++= Seq( "org.scalatest" %% "scalatest" % "3.1.2" % "test", )
AnyFunSuiteについて
Getting started with FunSuite等で見かけるorg.scalatest.FunSuite
ですが、ScalaTest 3.1.2では存在しません。org.scalatest.funsuite
以下に用途別でFunSuiteが存在しており、必要なものをextend
あるいはwith
する形になります。
import org.scalatest.funsuite.AnyFunSuite class MyTest extend AnyFunSuite { test("example") { // test case } }
org.scalatest.funsuite
以下のclassは以下の通りです。
InterFace | Class | UseCase |
---|---|---|
class | AnyFunSuite | StandardTest |
trait | AnyFunSuiteLike | StandardTest |
class | AsyncFunSuite | Async StandardTest |
trait | AsyncFunSuiteLike | Async StandardTest |
class | FixtureAnyFunSuite | StandardTest with Fixtures |
trait | FixtureAnyFunSuiteLike | StandardTest with Fixtures |
trait | FixtureAsyncFunSuite | Async StandardTest with Fixtures |
trait | FixtureAsyncFunSuiteLike | Async StandardTest with Fixtures |
Matchersについて
Using matchers等で見かける書き方も、3.1.2では正常には実行できません。
org.scalatest.matchers
以下からextend
あるいはwith
します。
import org.scalatest.funsuite.AnyFunSuite import org.scalatest.matchers.should.Matchers class MyTest extends AnyFunSuite with Matchers { test("example") { val a = "a" a should be ("a") } }
org.scalatest.matchers
以下には他に幾つもの類似したClassが存在します。テストするプロパティ名や結果をまとめて一つのClassにするものもあります。
今回はorg.scalatest.matchers.should.Matchers
をimportしてみました。matchers直下のClassはapply
を通す必要があり、記法のシンプルさを優先しつつ値確認を例としたかったためです。
InterFace | Class | UseCase |
---|---|---|
trait | BeMatcher | Value Check |
trait | Matcher | Object Check |
trait | BePropertyMatcher | Property Check |
class | BePropertyMatchResult | Check Result Assertion |
class | HavePropertyMatchResult | Check Result Assertion |
MatcherとBeMatcherの違いは、上記例でa should be ("a")
のうち、shouldにかかるのかbeにかかるのかの違いとなります。
具体的にはMatcherではshould以降、以下の様に値というよりも振る舞いそのものを確認します。
file should endWithExtension ("txt") file should not endWithExtension "txt" file should (exist and endWithExtension ("txt"))
BeMatcherではbe以降、結果そのものを一致確認します。
num should be (odd) num should not be (even)
Although BeMatcher and Matcher represent very similar concepts, they have no inheritance relationship because Matcher is intended for use right after should or must whereas BeMatcher is intended for use right after be.
あとがき
最新のpackage構成を追従しているドキュメントはそこまで多くなく、実際にコード上でimportする際にDeprecatedを避けていくと自然に今回のClassを使う形となりました。
matchersには幾つものClassがありますが、設計全体よりも出力値のテストを重点的に求められているのならshould.Matchers
を使うと柔軟にテスト可能だと感じました。
また、must.Matchers
も存在しますが、shouldとmustでの振る舞いにほぼ差がないようで好みの問題かもしれません。今回shouldを使った理由としては、検証作業中に読んだ記事で利用例が多かったというだけです。
// いずれも3以外は失敗する result must equal (3) result should equal (3) result must be (3) result should be (3)